package lk.icta.core.web.action;

import lk.icta.common.AppConstants;
import lk.icta.common.entity.Contacts;
import lk.icta.common.entity.Person;
import lk.icta.common.service.ContactsManager;
import lk.icta.common.service.DocumentManagementService;
import lk.icta.common.service.MailSenderService;
//import lk.icta.common.util.MailUtil;
import lk.icta.common.web.action.DocumentUploadAction;
import lk.icta.core.dto.MapDetails;
import lk.icta.core.entity.GOInterestInformation;
import lk.icta.core.entity.ModuleType;
import lk.icta.core.entity.Organization;
import lk.icta.core.entity.URMGOIUser;
import lk.icta.core.service.GOInterestManagementService;
import lk.icta.core.service.OrganisationManagementService;
import lk.icta.core.service.PersonManagementService;
import lk.icta.core.service.URMGOIUserManagementService;
import lk.icta.user.dao.RoleDAO;
import lk.icta.user.entity.User;
import lk.icta.user.service.UserManager;
import org.apache.struts2.interceptor.SessionAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * @author Tharanga Punchihewa
 */
public class InterestAction extends DocumentUploadAction implements SessionAware {
    private static final Logger logger = LoggerFactory.getLogger(InterestAction.class);
    private final PersonManagementService personManagementService;
    private final ContactsManager contactsManagerService;
    private final OrganisationManagementService organisationManagementService;
    private final UserManager userManager;
    private final URMGOIUserManagementService urmgoiUserManagementService;
    private final GOInterestManagementService goInterestManagementService;
    private final MailSenderService mailSenderService;
    private RoleDAO roleDAO;

    private Person headOfGO;
    private Organization organization;
    private Contacts contactOfHeadOfGO;
    private Person userDetail;
    private Contacts userContacts;
    private URMGOIUser urmgoiUser;
    private GOInterestInformation goInterestInformation;

    private List<Organization> organizationsList;
    private List<GOInterestInformation> goInterestInformationList;
    private Map<Integer, List<MapDetails>> mapDetailMap;
    private List<URMGOIUser> urmgoiUserList;
    private List<User> usersList;
    private Map<Integer, String> organizationMapList;
    private int organizationId;
    private long headOfGOId;
    private long goInterestInformationId;
    private long contactOfHeadOfGOId;
    private User registerUser;
    /*
    * editMode=0 -data entry unregistered organization
    * editMode=1 -edit unregistered organization information
    * editMode=2 -data entry registered organization
    * editMode =3 populate organization list to create OR-PII users
    * editMode =4  populate organization list to create UR-MGOI users
    * editMode =5  populate organization list to edit organization users
    * */
    private int editMode;
    private String orpiiUserId;
    private long urmgoiUserId;
    private String userRoleId;
    /*
    *
     *mode=0  - load organization list to edit
     *mode=1  - load organization list to active and inactive
     *mode =2 - load organization to to be register  
     *mode =3 - load organization List for create OR-PII Users
     *mode =4 - load organization List for create UR-MGOI Users  
     *mode =5 - load organization List for edit organization Users  
     *mode =6 - initEditGOInterestInformation
     *mode =7 - load GO Interest Information list to be approved by ORPII
     *mode =8 - load GO Interest Information list Active/InActive
     *mode =9 - load GO inital Information list Active/InActive
     *mode =10- load GO Interest Information list - Search Module
    **/
    private int pageMode;

    private String organizationName;

    public InterestAction(PersonManagementService personManagementService,
                          ContactsManager contactsManagerService,
                          OrganisationManagementService organisationManagementService,
                          UserManager userManager, RoleDAO roleDAO,
                          URMGOIUserManagementService urmgoiUserManagementService,
                          GOInterestManagementService goInterestManagementService,
                          DocumentManagementService documentManagementService,
                          MailSenderService mailSenderService) {
        super(documentManagementService);
        this.userManager = userManager;
        this.contactsManagerService = contactsManagerService;
        this.personManagementService = personManagementService;
        this.organisationManagementService = organisationManagementService;
        this.goInterestManagementService = goInterestManagementService;
        this.roleDAO = roleDAO;
        this.urmgoiUserManagementService = urmgoiUserManagementService;
        this.mailSenderService = mailSenderService;

    }

    public String initAddOrganisation() {
        organizationsList = organisationManagementService.getInitInfoOrganizationList(user);
        logger.debug("Load initial data entry organization list to capture other details by : {}", user.getUsername());
        pageMode = 9;
        return SUCCESS;
    }

    public String populateInitAddOrganization() {
        editMode = 0;
        organization = organisationManagementService.getOrganizationByIdUKey(organizationId, user);
        logger.debug("populate initial  information of organization by :{}", user.getUsername());
        return SUCCESS;
    }

    public String landInterests() {
        logger.debug("load Land Interests home by : {}", user.getUsername());
        return SUCCESS;
    }

    public String organizationalReports() {
        return SUCCESS;
    }

    public String loadActiveOrganizationList() {
        try {
//            organizationsList = organisationManagementService.getActiveOrganizationList(user);
            organizationsList = organisationManagementService.getActiveUnRegisterOrganizationList(user);
            logger.debug("Load Active ORganization list by : {}", user.getUsername());
        } catch (Exception e) {
            logger.debug("loding error in active organization list : {}", e);
        }
        return SUCCESS;
    }

    public String loadAllOrganizationList() {
        try {
            organizationsList = organisationManagementService.getAllOrganizations(user);
            logger.debug("Load Active ORganization list by : {}", user.getUsername());
        } catch (Exception e) {
            logger.debug("loding error in active organization list : {}", e);
        }
        return SUCCESS;
    }


    public String loadActiveUnRegisterOrganizationList() {
        pageMode = getPageMode();
        try {
            organizationsList = organisationManagementService.getActiveUnRegisterOrganizationList(user);
        } catch (Exception e) {
            logger.debug("loding error in organization list : {}", e);
        }
        return SUCCESS;
    }

    public String loadActiveRegisteredOrganizationList() {
        pageMode = getPageMode();
        try {
            organizationsList = organisationManagementService.getActiveRegisterOrganizationList(user);
            logger.debug("size of selected organization list is :{}", organizationsList.size());
        } catch (Exception e) {
            logger.debug("loding error in organization list : {}", e);
        }
        return SUCCESS;
    }

    public String addOrganisation() {
        logger.debug("Edit mode value is  : {}", editMode);
        if (editMode == 0 || editMode == 1) {
            organization.setType(Organization.Type.UN_REGISTERED);
        } else if (editMode == 2 || editMode == 3) {
            organization.setType(Organization.Type.REGISTERED);
        }
        if (AppConstants.ORPII_USER_ROLE.equals(user.getRole().getId())) {
            organization.setType(Organization.Type.EDIT_BY_ORPII);
        }
        try {
            if (editMode != 0) {
                logger.debug("edit org");
                editModeOrganization();
                if (editMode == 2 || editMode == 3) {
                    logger.debug("registr org");
                    addActionMessage(getText("organization_information_successfully_registered.label"));
                } else {
                    logger.debug("update org");
                    addActionMessage(getText("organization_information_successfully_updated.label"));
                }
            } else {
                logger.debug("add new org");
                addModeOrganization();
                addActionMessage(getText("organization_information_successfully_saved.label"));
            }
        } catch (Exception e) {
            addActionError(getText("unable_to_find_organization.label"));
            logger.error(e.getMessage());
            e.printStackTrace();
            return ERROR;
        }

//        addActionMessage(getText("organization_information_successfully_saved.label"));
        if (AppConstants.ORPII_USER_ROLE.equals(user.getRole().getId())) {
            sendMailToORMOI();
            return AppConstants.ORPII_USER_ROLE + SUCCESS;
        }
        return SUCCESS;
    }

    public String addOrganisationAndCreateORPIIUser() {
        logger.debug("AddOrganisationAndCreateORPIIUser");
        //kkk
        String addOrganisation = addOrganisation();
        if (addOrganisation.equals(SUCCESS)) {
            logger.debug("AddO rganisation Success");
            organizationId = getOrganizationId();
            userRoleId = AppConstants.ORPII_USER_ROLE;
            String createORPIIUser = createORPIIUser();
            if (createORPIIUser.equals(SUCCESS)) {
                logger.debug("CreateORPIIUser Success");
                //addActionMessage(getText("organization_information_successfully_saved.label"));                return SUCCESS;
                return SUCCESS;
            } else {
                logger.debug("CreateORPIIUser Fail");
                return ERROR;
            }

        } else {
            logger.debug("AddO rganisation Fail");
            //addActionError(getText("unable_to_find_organization.label"));
            return ERROR;
        }
    }


    //save due date
    public String saveDueDate() {
        logger.debug("Save due date  : {}", editMode);

        try {
            if (organization != null) {
                saveDueDateOfOrganization();
                organization = organisationManagementService.getOrganizationByIdUKey(organization.getId(), user);
                headOfGO = organization.getContactPerson();
                contactOfHeadOfGO = headOfGO.getContacts();
            }

        } catch (Exception e) {
            addActionError(getText("unable_to_find_organization.label"));
            logger.error("error in saving due date : {}", e);
            return ERROR;
        }

        addActionMessage(getText("letter_generated_successfully.label"));

        return SUCCESS;
    }


    //save due date

    private void saveDueDateOfOrganization() {
        organisationManagementService.updateDueDate(organization, user);
    }

    private void editModeOrganization() {
        logger.debug("start to edit organization : {}", organization.getId());
        contactsManagerService.updateContact(contactOfHeadOfGO, user);
        headOfGO.setContacts(contactOfHeadOfGO);
        personManagementService.updatePerson(headOfGO, user);
        organization.setContactPerson(headOfGO);
        organisationManagementService.updateOrganization(organization, user);
    }

    private void addModeOrganization() {
        // contactsManagerService.addContact(contactOfHeadOfGO, user);
        //logger.debug("contact detail of the {} added , contact detail id is : {}",
        //  headOfGO.getName(), contactOfHeadOfGO.getId());
        headOfGO.setContacts(contactOfHeadOfGO);
        // personManagementService.addPerson(headOfGO, user);
        //  logger.debug(" {} was added as the {}'s head of the department",
        //   headOfGO.getName(), organization.getOrganizationNameEn());
        organization.setContactPerson(headOfGO);
        if (organization.getId() > 0) {
            organisationManagementService.updateOrganization(organization, user);
        } else {
            organisationManagementService.addOrganization(organization, user);
        }

    }

    public String initOrganizationUsersList() {
        pageMode = getPageMode();
        setORPIIUserList();
        if (usersList != null) {
            logger.debug("Size of user list : {}", usersList.size());
        }
        return SUCCESS;
    }

    public String activeOrganization() {
        organization = organisationManagementService.getOrganizationByIdUKey(organizationId, user);
        organisationManagementService.activeOrganization(organization, user);
        logger.debug("The organization : {} active by :{}", organization.getOrganizationNameEn(), user.getUsername());
        organizationsList = organisationManagementService.getAllOrganizations(user);
        pageMode = 1;
        return SUCCESS;
    }

    public String inactiveOrganization() {
        organization = organisationManagementService.getOrganizationByIdUKey(organizationId, user);
        organisationManagementService.inactiveOrganization(organization, user);
        logger.debug("The organization : {} inactive by :{}", organization.getOrganizationNameEn(), user.getUsername());
        organizationsList = organisationManagementService.getAllOrganizations(user);
        pageMode = 1;
        return SUCCESS;
    }

    public String initCreateORPIIUsers() {
        organizationId = getOrganizationId();
        userRoleId = AppConstants.ORPII_USER_ROLE;
        return SUCCESS;
    }

    public String initHome() {
        logger.debug("Load Home page by : {}", user.getUsername());
        return SUCCESS;
    }

    public String activeURMGOIUserAccount() {
        registerUser = userManager.getUserByUserName(orpiiUserId);
        userManager.activeUser(registerUser, user);
        logger.debug("UR-MGOI User: {} active by : {}", registerUser.getUsername(), user.getUsername());
        usersList = userManager.getNewURMGOIUsersByOrganization(organizationId, user);
        logger.debug("Load All new user for organization of organization id : {} by : {}",
                organizationId, user.getUsername());
        addActionMessage(getText("user_approved_successfully.label"));
        return SUCCESS;
    }

    public String initGenerateLatter() {
        organization = organisationManagementService.getOrganizationByIdUKey(organizationId, user);
        headOfGO = organization.getContactPerson();
        contactOfHeadOfGO = headOfGO.getContacts();

        return SUCCESS;
    }


    public String initRegisterOrganization() {
        editMode = 2;
        try {
            organization = organisationManagementService.getOrganizationByIdUKey(organizationId, user);
            headOfGO = organization.getContactPerson();
            contactOfHeadOfGO = headOfGO.getContacts();
            logger.debug("Populate information : {} organization to register by : {}",
                    organization.getOrganizationNameEn(), user.getUsername());
        } catch (Exception e) {
            addActionError(getText("unable_to_find_organization.label"));
            logger.error("error in finding init detail of the organization :{}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String initManageRegisterOrganization() {
        organizationsList = organisationManagementService.getRegisterOrganizationList(user);
        logger.debug("Load register organization list by : {}", user.getUsername());
        return SUCCESS;
    }

    public String newURMGOIUserAccountList() {
        organizationId = user.getOrganization().getId();
        usersList = userManager.getNewURMGOIUsersByOrganization(organizationId, user);
        logger.debug("Load All new user for organization of organization id : {} by : {}", organizationId, user.getUsername());
        return SUCCESS;
    }

    public String initcreateURMGOIUsers() {
        urmgoiUser = urmgoiUserManagementService.getURMGOIByIdUKey(urmgoiUserId, user);
        try {
            organizationId = urmgoiUser.getOrganization().getId();
            userRoleId = AppConstants.URMGOI_USER_ROLE;
            registerUser = new User();
            if (urmgoiUser.getUserDetail() != null) {
                registerUser.setFullName(urmgoiUser.getUserDetail().getName());
                if (urmgoiUser.getUserDetail().getContacts() != null) {
                    registerUser.setAddress(urmgoiUser.getUserDetail().getContacts().getAddress());
                    registerUser.setEmail(urmgoiUser.getUserDetail().getContacts().getEmail());
                    registerUser.setMobile(urmgoiUser.getUserDetail().getContacts().getMobile());
                    registerUser.setLandPhone(urmgoiUser.getUserDetail().getContacts().getLandPhone());
                }
            }

        } catch (Exception e) {
            logger.error("error in creating UR-MGOI user : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String initCreateURMGOIUsers() {
        logger.debug("Attempt  to add ur-moi users");
        return SUCCESS;
    }

    public String createURMGOIUsers() {
        logger.debug("Attempt  to  add ur-moi users");
        try {
            if (editMode == 1) {
                //edit by ORPII
                editURMOIUser();
                addActionMessage(getText("user_updated_successfully.label"));
            } else if (editMode == 2) {
                //edit by URMGOI
                boolean isUpdate = editPersonalInformationByURMOIUser();
                if (isUpdate) {

                    String msg = "Information about " + user.getFullName() + " in " + user.getOrganization().getOrganizationNameEn() +
                            " organization  has been modified. " +
                            "\n " + user.getUsername();

                    boolean isMailSent = sendMailToORPII("Edit Personal information", msg);
                    String mailSendStatusStr = "";
                    if (!isMailSent) {
                        mailSendStatusStr = getText("mail_send_fail.label");
                    }
                    addActionMessage(getText("user_updated_successfully.label") + mailSendStatusStr);
                } else {
                    addActionMessage(getText("user_updated_fail.label"));

                }

            } else {
                try {
                    //  contactsManagerService.addContact(userContacts, user);
                    userDetail.setContacts(userContacts);
                    //  personManagementService.addPerson(userDetail, user);
                    URMGOIUser urmgoiUser = new URMGOIUser();
                    urmgoiUser.setUserDetail(userDetail);
                    urmgoiUser.setOrganization(user.getOrganization());
                    urmgoiUser.setStatus(URMGOIUser.State.ACTIVE);
                    urmgoiUserManagementService.addORMGOIUser(urmgoiUser, user);
                } catch (Exception e) {
                    logger.debug("Exception e : {}", e);
                }
                addActionMessage(getText("user_registered_successfully.label"));
            }
        } catch (Exception e) {
            addActionError("Error adding URMGOI user");
            e.printStackTrace();
        }

        return SUCCESS;
    }


    private void editURMOIUser() {
        logger.debug("Attempt  to  update ur-moi users {}");
        try {
            contactsManagerService.updateContact(userContacts, user);
            userDetail.setContacts(userContacts);
            personManagementService.updatePerson(userDetail, user);
            urmgoiUser.setUserDetail(userDetail);
            urmgoiUser.setOrganization(user.getOrganization());
            urmgoiUser.setStatus(URMGOIUser.State.ACTIVE);
            urmgoiUserManagementService.updateORMGOIUser(urmgoiUser, user);
        } catch (Exception e) {
            logger.error("error in editing UR-MGOI user : {}", e);
        }

    }

    private boolean editPersonalInformationByURMOIUser() {
        logger.debug("Attempt  to  editPersonalInformationByURMOIUser {}");
        try {
            contactsManagerService.updateContact(userContacts, user);
            userDetail.setContacts(userContacts);
            personManagementService.updatePerson(userDetail, user);
            //urmgoiUser.setUserDetail(userDetail);
            //urmgoiUser.setOrganization(user.getOrganization());
            //urmgoiUser.setStatus(URMGOIUser.State.ACTIVE);

            urmgoiUser = urmgoiUserManagementService.getURMGOIByIdUKey(urmgoiUser.getId(), user);
            urmgoiUser.setUserDetail(userDetail);
            urmgoiUser.setOrganization(user.getOrganization());

            urmgoiUserManagementService.updateORMGOIUser(urmgoiUser, user);
            return true;
        } catch (Exception e) {
            logger.error("error in editing PersonalInformationByURMOIUserr : {}", e);
            return false;
        }

    }

    public String urmgoiUserList() {
        if (AppConstants.ORPII_USER_ROLE.equals(user.getRole().getId())) {
            organizationId = user.getOrganization().getId();
        } else if (AppConstants.URMGOI_USER_ROLE.equals(user.getRole().getId())) {
            organizationId = getOrganizationId();
        }
        userRoleId = AppConstants.URMGOI_USER_ROLE;
        urmgoiUserList = urmgoiUserManagementService.getURMGOIUserListByOrganization(organizationId, user);
        return SUCCESS;
    }

    public String initEditURMGOIUser() {
        urmgoiUser = urmgoiUserManagementService.getURMGOIByIdUKey(urmgoiUserId, user);
        userDetail = personManagementService.getPersonByIdUKey(urmgoiUser.getUserDetail().getId(), user);
        userContacts = contactsManagerService.getContactsByIdUKey(userDetail.getContacts().getId(), user);
        editMode = 1;
        logger.debug("Populate user detail of : {} ", urmgoiUser.getUserDetail().getName());
        return SUCCESS;
    }

    public String loadPersonalDetailsOfURMGOIUser() {

        logger.debug("loadPersonalDetailsOf URMGOIUser:");

        if (AppConstants.URMGOI_USER_ROLE.equals(user.getRole().getId())) {

            //urmgoiUserId = urmgoiUserList.get(0).getId();
            //logger.debug("loadPersonalDetailsOf urmgoiUserId : {}", urmgoiUserId);
            // urmgoiUser = urmgoiUserManagementService.getURMGOIByIdUKey(urmgoiUserId, user);

            urmgoiUser = urmgoiUserManagementService.getURMGOIByUserName(user);
            logger.debug("\n \n loadPersonalDetailsOf urmgoiUserId : {}", urmgoiUser.getId());

            userDetail = personManagementService.getPersonByIdUKey(urmgoiUser.getUserDetail().getId(), user);
            userContacts = contactsManagerService.getContactsByIdUKey(userDetail.getContacts().getId(), user);
            editMode = 2;
            logger.debug("Populate user detail of : {} ", urmgoiUser.getUserDetail().getName());
        }
        return SUCCESS;
    }

    public String loadInterestMapByURMGOIUser() {

        logger.debug("loadInterestMap By {}r:", user.getRole().getName());

        if (AppConstants.URMGOI_USER_ROLE.equals(user.getRole().getId()) || AppConstants.ORPII_USER_ROLE.equals(user.getRole().getId())) {
            logger.debug("loadInterestMap By URMGOIUser and PII:");
            goInterestInformationList = goInterestManagementService.getGOInterestInformationListByOrganizationId(user);
            logger.debug("\n \n loadInterestMap List Size : {}", goInterestInformationList.size());
            //organizationName=user.getOrganization().getOrganizationNameEn();
            mapDetailMap = new HashMap<Integer, List<MapDetails>>();

            //for(Organization org : organizationsList){
            List<MapDetails> mapList = new ArrayList<MapDetails>();
            int orgId = user.getOrganization().getId();
            String orgName = organisationManagementService.getOrganizationByIdUKey(orgId, user).getOrganizationNameEn();

            for (GOInterestInformation goInfo : goInterestInformationList) {

                if (orgId == goInfo.getOrganizationId()) {
                    //String colorCode="5000F014";
                    MapDetails mapDetails = new MapDetails();
                    mapDetails.setLandName(orgName);
                    mapDetails.setLandId(goInfo.getId());
                    mapDetails.setReferenceNumber(goInfo.getReferenceNumber());
                    mapDetails.setKmlString(goInfo.getKmlString());
                    mapDetails.setKmlMiddlePoint(goInfo.getKmlMiddlePoint());
                    mapDetails.setKmlLandArea(goInfo.getKmlLandArea());
                    // mapDetails.setColorCode(colorCode);

                    mapList.add(mapDetails);
                    mapDetailMap.put(orgId, mapList);
                }
            }
            logger.debug("\n \n orgName : {} == List Size {}", orgName, mapList.size());
            //}
            logger.debug("\n \n goInfo Map Size : {}", mapDetailMap.size());
        } else if (AppConstants.ORMOI_USER_ROLE.equals(user.getRole().getId())) {
            logger.debug("loadInterestMap By ORMGOIUser:");

            goInterestInformationList = goInterestManagementService.getGOInterestInformationList(user);
            logger.debug("\n \n loadInterestMap List Size : {}", goInterestInformationList.size());


            organizationsList = organisationManagementService.getActiveOrganizationList(user);

            mapDetailMap = new HashMap<Integer, List<MapDetails>>();

            for (Organization org : organizationsList) {
                List<MapDetails> mapList = new ArrayList<MapDetails>();
                int orgId = org.getId();
                String orgName = organisationManagementService.getOrganizationByIdUKey(orgId, user).getOrganizationNameEn();
                //String colorCode="50FF7800";
                for (GOInterestInformation goInfo : goInterestInformationList) {

                    if (orgId == goInfo.getOrganizationId()) {

                        MapDetails mapDetails = new MapDetails();
                        mapDetails.setLandName(orgName);
                        mapDetails.setLandId(goInfo.getId());
                        mapDetails.setReferenceNumber(goInfo.getReferenceNumber());
                        mapDetails.setKmlString(goInfo.getKmlString());
                        mapDetails.setKmlMiddlePoint(goInfo.getKmlMiddlePoint());
                        mapDetails.setKmlLandArea(goInfo.getKmlLandArea());
                        //mapDetails.setColorCode(colorCode);

                        mapList.add(mapDetails);
                        mapDetailMap.put(orgId, mapList);
                    }
                }
                logger.debug("\n \n orgName : {} == List Size {}", orgName, mapList.size());
            }
            logger.debug("\n \n goInfo Map Size : {}", mapDetailMap.size());


        }
        return SUCCESS;
    }


    public String activeURMGOIUser() {
        urmgoiUser = urmgoiUserManagementService.getURMGOIByIdUKey(urmgoiUserId, user);
        logger.debug("Attempt  to  Active ur-moi user : {}", urmgoiUser.getUserDetail().getName());
        urmgoiUserManagementService.activeURMGOIUser(urmgoiUser, user);
        urmgoiUserList = urmgoiUserManagementService.getURMGOIUserListByOrganization(1, user);
        return SUCCESS;
    }

    public String inactiveURMGOIUser() {
        urmgoiUser = urmgoiUserManagementService.getURMGOIByIdUKey(urmgoiUserId, user);
        logger.debug("Attempt  to  inactive ur-moi user : {}", urmgoiUser.getUserDetail().getName());
        urmgoiUserManagementService.inactiveURMGOIUser(urmgoiUser, user);
        urmgoiUserList = urmgoiUserManagementService.getURMGOIUserListByOrganization(1, user);
        return SUCCESS;
    }

    public String initurmgoiUsersManage() {

        return SUCCESS;
    }
    //kk
    public String createORPIIUser() {
        logger.debug("Attempt  to create orpii user :{}", getRegisterUser().getUsername());
        try {
            //   generate a random password
            String password = getRandomPassword();
            //todo set random password
            registerUser.setPasswordHash("password");
            registerUser.setOrganization(organisationManagementService.getOrganizationByIdUKey(organizationId, user));
            registerUser.setRole(roleDAO.getRole(userRoleId));
            /*editMode = 1  update user
            * editMode !=1  Add new user
            * */
            if (editMode == 1) {
                logger.debug("Attempt  to update organization user :{}", getRegisterUser().getUsername());
                userManager.updateUser(registerUser, user);
                logger.debug("updated organization  user :{}", getRegisterUser().getUsername());
                addActionMessage(getText("user_updated_successfully.label"));
            } else {
                pageMode = 5;
                userManager.createUser(registerUser, user);
                String mailSendStatusStr = "";
                if (AppConstants.ORPII_USER_ROLE.equals(userRoleId)) {
                    //Send user name and password to user if register user is a ORPII
                    boolean isMailSent = sendPasswordMail(registerUser, password);
                    if (!isMailSent) {
                        mailSendStatusStr = getText("mail_send_fail.label");
                    }
                } else if (AppConstants.URMGOI_USER_ROLE.equals(userRoleId)) {
                    //update the URMGOI Table userName
                    urmgoiUser = urmgoiUserManagementService.getURMGOIByIdUKey(urmgoiUserId, user);
                    urmgoiUser.setUsername(registerUser.getUsername());
                    urmgoiUserManagementService.updateORMGOIUser(urmgoiUser, user);

                    //Send a notification to all  OR-PII user in Organization if register user is a UR-MGOI

                    boolean isMailSent = sendMassageMail();
                    if (!isMailSent) {
                        mailSendStatusStr = getText("mail_send_fail.label");
                    }
                }
                addActionMessage(getText("user_created_successfully.label") + ". " + mailSendStatusStr);
            }
            usersList = userManager.getUsersByOrganization(organizationId, user);
//            addActionMessage(getText("user_created_successfully.label"));
            return SUCCESS;
        } catch (Exception e) {
            logger.debug("Exception in add/edit organization user :{}", e);
            /* switch (e.getErrorCode()) {
                case ErrorCodes.ENTITY_ALREADY_EXIST:
                    addActionError(getText("unable_to_register_user.label") + " " + getText("user_already_assigned.label"));
                    break;
                default:
                    logger.debug("Exception in add/edit organization user :{}", e);
            }*/
        }
        return ERROR;
    }

    public String activeORPIIUser() {
        User orpiiUser = userManager.getUserByUserName(orpiiUserId);
        userManager.activeUser(orpiiUser, user);
        logger.debug(" {} active by : {}", orpiiUser.getFullName(), user.getUsername());
        setORPIIUserList();
        pageMode = 6;
        return SUCCESS;
    }

    public String inactiveORPIIUser() {
        User orpiiUser = userManager.getUserByUserName(orpiiUserId);
        userManager.inactiveUser(orpiiUser, user);
        logger.debug(" {} inactive by : {}", orpiiUser.getFullName(), user.getUsername());
        setORPIIUserList();
        pageMode = 6;
        return SUCCESS;
    }

    public String initEditORPIIUserInfo() {
        registerUser = userManager.getUserByUserName(orpiiUserId);
        organizationId = registerUser.getOrganization().getId();
        orpiiUserId = registerUser.getUsername();
        userRoleId = registerUser.getRole().getId();
        editMode = 1;
        return SUCCESS;
    }

    public String initEditOrganizationInfo() {
        editMode = getEditMode();
        /*If the user is ORPII */
        if (AppConstants.ORPII_USER_ROLE.equals(user.getRole().getId())) {
            organizationId = user.getOrganization().getId();
            editMode = 3;
        }
        organization = organisationManagementService.getOrganizationByIdUKey(organizationId, user);
        headOfGOId = organization.getContactPerson().getId();
        headOfGO = personManagementService.getPersonByIdUKey(headOfGOId, user);
        contactOfHeadOfGOId = headOfGO.getContacts().getId();
        contactOfHeadOfGO = contactsManagerService.getContactsByIdUKey(contactOfHeadOfGOId, user);

        return SUCCESS;
    }

    private void setORPIIUserList() {
        logger.debug("get organization user list by : {} ,for organization id : {}", user.getUsername(), organizationId);
        usersList = userManager.getUsersByOrganization(organizationId, user);
    }

    public String loadOrganizationList() {
        try {
            organizationsList = organisationManagementService.getRegisterOrganizationList(user);
            logger.debug("organization list size is : {}", organizationsList.size());
            if (organizationId > 0) {
                usersList = userManager.getUsersByOrganization(organizationId, user);
            }
        } catch (Exception e) {
            logger.debug("error in organization list : {}", e);
        }

        return SUCCESS;
    }

    public String unRegisteredOrganizationReport() {
        organizationsList = organisationManagementService.getActiveUnRegisterOrganizationList(user);
        return SUCCESS;
    }

    public String addInterestInfoInit() {
        editMode = 0;
        findDocumentCategoryList(ModuleType.OTHER);
        return SUCCESS;
    }

    public String addInterestInfo() {
        if (editMode == 0) {
            goInterestInformation.setDocumentList(getUploadedfileList(ModuleType.OTHER));
            goInterestManagementService.addGOInterestInformation(goInterestInformation, user);
            //e-mail message
            String msg = "Information about " + user.getOrganization().getOrganizationNameEn() +
                    " organization Interest has been added and to Approve the information. " +
                    "\n " + user.getUsername();
            boolean isMailSent = sendMailToORPII("Add GO information", msg);
            String mailSendStatusStr = "";
            if (!isMailSent) {
                mailSendStatusStr = getText("mail_send_fail.label");
            }
            addActionMessage(getText("go_interest_information_successfully_saved.label") + ". " + mailSendStatusStr);

        } else if (editMode == 1) {  //edit
            goInterestInformation.setDocumentList(getUploadedfileList(ModuleType.OTHER));
            //Set GEO Data
            GOInterestInformation oldGoInterestInformation = goInterestManagementService.getGOInterestInformationById(goInterestInformation.getId(), user);
            goInterestInformation.setKmlLandArea(oldGoInterestInformation.getKmlLandArea());
            goInterestInformation.setKmlString(oldGoInterestInformation.getKmlString());
            goInterestInformation.setKmlMiddlePoint(oldGoInterestInformation.getKmlMiddlePoint());

            goInterestInformation.setOrganizationId(oldGoInterestInformation.getOrganizationId());

            goInterestManagementService.updateGOInterestInformation(goInterestInformation, user);
            //e-mail message
            String msg = "Information about " + user.getOrganization().getOrganizationNameEn() +
                    " organization Interest has been modified and to Approve the information. " +
                    "\n " + user.getUsername();

            boolean isMailSent = sendMailToORPII("Modify GO information", msg);
            String mailSendStatusStr = "";
            if (!isMailSent) {
                mailSendStatusStr = getText("mail_send_fail.label");
            }
            addActionMessage(getText("go_interest_information_successfully_updated.label") + ". " + mailSendStatusStr);
        }
        return SUCCESS;
    }

    public String editGOInterestInformationList() {
        try {
            pageMode = 6;
            //goInterestInformationList = goInterestManagementService.getGOInterestInformationListToBeEdit(user);
            //goInterestInformationList = goInterestManagementService.getGOInterestInformationList(user);
            goInterestInformationList = goInterestManagementService.getGOInterestInformationListByOrganizationId(user);
        } catch (Exception e) {
            logger.error("Error in editing GO information  : {}", e);
        }

        return SUCCESS;
    }

    public String approveGOInterestInformationList() {
        try {
            pageMode = 7;
            goInterestInformationList = goInterestManagementService.getGOInterestInformationListToBeApproved(user);
        } catch (Exception e) {
            logger.error("Error in Approving GO information: {}", e);
        }

        return SUCCESS;
    }

    public String initApproveGOInterestInformation() {
        pageMode = 7;
        goInterestInformation = goInterestManagementService.getGOInterestInformationById(goInterestInformationId, user);
        return SUCCESS;
    }

    public String approveInterestInfo() {
        logger.debug("Approving Interest Information : {} ", goInterestInformation.getId());
        try {
            goInterestInformation = goInterestManagementService.getGOInterestInformationById(goInterestInformation.getId(), user);
            goInterestManagementService.approveGOInterestInformation(goInterestInformation, user);
            addActionMessage(getText("go_interest_information_successfully_approved.label"));
            return SUCCESS;
        } catch (Exception e) {
            logger.error("Error in approving Interest Information : {}", e);
            return ERROR;
        }

    }

    public String rejectInterestInfo() {
        logger.debug("Rejecting Interest Information : {} ", goInterestInformation.getId());
        try {
            String comment = goInterestInformation.getComment();
            goInterestInformation = goInterestManagementService.getGOInterestInformationById(goInterestInformation.getId(), user);
            goInterestInformation.setComment(comment);
            goInterestManagementService.rejectGOInterestInformation(goInterestInformation, user);
            boolean isMailSent = informMailToURMGOI();
            String mailSendStatusStr = "";
            if (!isMailSent) {
                mailSendStatusStr = getText("mail_send_fail.label");
            }
            addActionMessage(getText("go_interest_information_successfully_reject.label") + ". " + mailSendStatusStr);
            return SUCCESS;
        } catch (Exception e) {
            logger.error("Error in rejecting Interest Information : {}", e);
            return ERROR;
        }

    }

    public String loadGOInterestInformationList() {
        pageMode = 8;
        goInterestInformationList = goInterestManagementService.getGOInterestInformationList(user);
        return SUCCESS;
    }

    public String activeGOInterestInformation() {
        goInterestInformation = goInterestManagementService.getGOInterestInformationById(goInterestInformationId, user);
        goInterestManagementService.activeGOInterestInformation(goInterestInformation, user);
        pageMode = 8;
        goInterestInformationList = goInterestManagementService.getGOInterestInformationList(user);
        addActionMessage(getText("go_interest_information_successfully_activated.label"));
        return SUCCESS;
    }

    public String inactiveGOInterestInformation() {
        goInterestInformation = goInterestManagementService.getGOInterestInformationById(goInterestInformationId, user);
        goInterestManagementService.inactiveGOInterestInformation(goInterestInformation, user);
        pageMode = 8;
        goInterestInformationList = goInterestManagementService.getGOInterestInformationList(user);
        addActionMessage(getText("go_interest_information_successfully_deactivated.label"));
        return SUCCESS;
    }

    public String initEditGOInterestInfo() {
        editMode = 1;
        goInterestInformation = goInterestManagementService.getGOInterestInformationById(goInterestInformationId, user);
        findDocumentCategoryList(ModuleType.OTHER);
        populateUploadedFiles(goInterestInformationId, ModuleType.OTHER);
        return SUCCESS;
    }

    public String initSearchGOInterestInformation() {
        try {
            pageMode = 10;
            goInterestInformationList = goInterestManagementService.getGOInterestInformationList(user);
        } catch (Exception e) {
            logger.error("Error in searching GO information  : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String searchGOInterestInformation() {
        pageMode = 10;
        goInterestInformation = goInterestManagementService.getGOInterestInformationById(goInterestInformationId, user);
        return SUCCESS;
    }


    private String getRandomPassword() {
        StringBuffer buffer = new StringBuffer();
        Random random = new Random();
        int length = random.nextInt(6) + 8;
        char[] charArray = new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
                'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
                'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
                'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7',
                '8', '9'};
        for (int i = 0; i < length; i++) {
            buffer.append(charArray[random.nextInt(charArray.length)]);
        }
        return buffer.toString();
    }

    private boolean sendPasswordMail(User newUser, String password) {
        String msg = "Dear " + newUser.getFullName() + ", \n" +
                "Welcome to the Government Land MIS System!" +
                "\n Your account for govLandMIS has been created successfully.\n Use the following account details to login to the system. \n" +
                "\n Username : " + newUser.getUsername() +
                "\n password : " + password +
                "\n Please Verify your Personal Details and Change your password at first login.\n" +
                "Enjoy! \n" +
                " " + user.getUsername();
        //mailUtil.sendMail("from@no-spam.com", newUser.getEmail(), "GovLandMIS : OR-PII User Registration", msg);

        return mailSenderService.sendMail("from@no-spam.com", newUser.getEmail(), "GovLandMIS : OR-PII User Registration", msg);


    }

    private boolean sendMassageMail() {
        String msg = "User Account for UR-MGOI User : " + registerUser.getUsername()
                + "was created. \n Please Active his Account.";
        usersList = userManager.getORPIIUsersByOrganization(registerUser.getOrganization().getId(), user);
        boolean mailSent = true;
        for (User u : usersList) {
            String mail = u.getEmail();
            mailSent = mailSenderService.sendMail("from@no-spam.com", mail, "GovLandMIS : UR-MGOI User Registration", msg);
        }
        return mailSent;
    }

    private boolean sendMailToORMOI() {
        String msg = "Information about " + organization.getOrganizationNameEn() + "organization edit by " +
                user.getUsername() + "Please approve or reject those changes";
        usersList = userManager.getUsersByRole(AppConstants.ORMOI_USER_ROLE, user);
        boolean mailSent = true;
        for (User u : usersList) {
            String mail = u.getEmail();
            mailSent = mailSenderService.sendMail("from@no-spam.com", mail, "Modify GO information" +
                    "", msg);
        }
        return mailSent;

    }

    private boolean sendMailToORPII(String subject, String message) {
        logger.error("InformMailTo ORPII");

        usersList = userManager.getUsersByRole(AppConstants.ORPII_USER_ROLE, user);
        boolean mailSent = true;
        for (User u : usersList) {
            if (u.getOrganization().getId() == user.getOrganization().getId()) {
                String mail = u.getEmail();
                mailSent = mailSenderService.sendMail("from@no-spam.com", mail, subject, message);
            }
        }
        return mailSent;

    }

    private boolean informMailToURMGOI() {
        logger.error("InformMailTo URMGOI");
        String msg = "Updated Information has not been approved." +
                "\n Please Log onto the SLMS to review the changes required." +
                "\n GOInterest Information ID - " + goInterestInformation.getId() +
                "\n GOInterest Information rejected by " +
                "\n " + user.getUsername();
        usersList = userManager.getUsersByRole(AppConstants.URMGOI_USER_ROLE, user);
        boolean mailSent = true;
        if (usersList != null) {
            for (User u : usersList) {
                logger.error("InformMailTo URMGOI usersList size:{}", usersList.size());
                if (u.getOrganization().getId() == user.getOrganization().getId()) {
                    String mail = u.getEmail();
                    mailSent = mailSenderService.sendMail("from@no-spam.com", mail, "Modify GO information" +
                            "", msg);
                }
            }
        }
        return mailSent;

    }

    public Person getHeadOfGO() {
        return headOfGO;
    }

    public void setHeadOfGO(Person headOfGO) {
        this.headOfGO = headOfGO;
    }

    public Organization getOrganization() {
        return organization;
    }

    public void setOrganization(Organization organization) {
        this.organization = organization;
    }

    public Contacts getContactOfHeadOfGO() {
        return contactOfHeadOfGO;
    }

    public void setContactOfHeadOfGO(Contacts contactOfHeadOfGO) {
        this.contactOfHeadOfGO = contactOfHeadOfGO;
    }

    public List<Organization> getOrganizationsList() {
        return organizationsList;
    }

    public void setOrganizationsList(List<Organization> organizationsList) {
        this.organizationsList = organizationsList;
    }

    public int getOrganizationId() {
        return organizationId;
    }

    public void setOrganizationId(int organizationId) {
        this.organizationId = organizationId;
    }

    public int getEditMode() {
        return editMode;
    }

    public void setEditMode(int editMode) {
        this.editMode = editMode;
    }

    public long getHeadOfGOId() {
        return headOfGOId;
    }

    public void setHeadOfGOId(long headOfGOId) {
        this.headOfGOId = headOfGOId;
    }

    public long getContactOfHeadOfGOId() {
        return contactOfHeadOfGOId;
    }

    public void setContactOfHeadOfGOId(long contactOfHeadOfGOId) {
        this.contactOfHeadOfGOId = contactOfHeadOfGOId;
    }

    public List<User> getUsersList() {
        return usersList;
    }

    public void setUsersList(List<User> usersList) {
        this.usersList = usersList;
    }

    public User getRegisterUser() {
        return registerUser;
    }

    public void setRegisterUser(User registerUser) {
        this.registerUser = registerUser;
    }

    public String getOrpiiUserId() {
        return orpiiUserId;
    }

    public void setOrpiiUserId(String orpiiUserId) {
        this.orpiiUserId = orpiiUserId;
    }

    public Person getUserDetail() {
        return userDetail;
    }

    public void setUserDetail(Person userDetail) {
        this.userDetail = userDetail;
    }

    public Contacts getUserContacts() {
        return userContacts;
    }

    public void setUserContacts(Contacts userContacts) {
        this.userContacts = userContacts;
    }

    public List<URMGOIUser> getUrmgoiUserList() {
        return urmgoiUserList;
    }

    public void setUrmgoiUserList(List<URMGOIUser> urmgoiUserList) {
        this.urmgoiUserList = urmgoiUserList;
    }

    public long getUrmgoiUserId() {
        return urmgoiUserId;
    }

    public void setUrmgoiUserId(long urmgoiUserId) {
        this.urmgoiUserId = urmgoiUserId;
    }

    public Map<Integer, String> getOrganizationMapList() {
        return organizationMapList;
    }

    public void setOrganizationMapList(Map<Integer, String> organizationMapList) {
        this.organizationMapList = organizationMapList;
    }

    public String getUserRoleId() {
        return userRoleId;
    }

    public void setUserRoleId(String userRoleId) {
        this.userRoleId = userRoleId;
    }

    public int getPageMode() {
        return pageMode;
    }

    public void setPageMode(int pageMode) {
        this.pageMode = pageMode;
    }

    public GOInterestInformation getGoInterestInformation() {
        return goInterestInformation;
    }

    public void setGoInterestInformation(GOInterestInformation goInterestInformation) {
        this.goInterestInformation = goInterestInformation;
    }

    public List<GOInterestInformation> getGoInterestInformationList() {
        return goInterestInformationList;
    }

    public void setGoInterestInformationList(List<GOInterestInformation> goInterestInformationList) {
        this.goInterestInformationList = goInterestInformationList;
    }

    public long getGoInterestInformationId() {
        return goInterestInformationId;
    }

    public void setGoInterestInformationId(long goInterestInformationId) {
        this.goInterestInformationId = goInterestInformationId;
    }

    public URMGOIUser getUrmgoiUser() {
        return urmgoiUser;
    }

    public void setUrmgoiUser(URMGOIUser urmgoiUser) {
        this.urmgoiUser = urmgoiUser;
    }


    public String getOrganizationName() {
        return organizationName;
    }

    public void setOrganizationName(String organizationName) {
        this.organizationName = organizationName;
    }


    public Map<Integer, List<MapDetails>> getMapDetailMap() {
        return mapDetailMap;
    }

    public void setMapDetailMap(Map<Integer, List<MapDetails>> mapDetailMap) {
        this.mapDetailMap = mapDetailMap;
    }
}
